from flask import Blueprint,request,jsonify,make_response
from  flask import  current_app as app
import json
import os
import uuid
import  datetime
from utils.mylist import myfile
from utils.db import  db
from utils.comm import xtree
from utils.myes import Es
from utils.comm import  get_data
from utils.jwts import myjwt
from utils.myacl import acl
from utils.myrbac import rbac
from utils.redisconn import  r

bp_user = Blueprint('users',__name__)


#用户登录
@bp_user.route('/login/',methods=['POST'])
def login():
    data = get_data()
    sql = "select * from users where mobile='%s'"%(data['mobile'])
    res = db.find_one(sql)
    #判断用户是否存在
    if res:
        if res['password'] == data['password']:
            #生成token
            data = {'data':{'mobile':res['mobile'],'userid':res['id'],'name':res['name']}}
            token = myjwt.jwt_encode(data)
            #用户权限 该用户权限集 这边只获取前端权限
            resall = acl.get_page_resource(res['id'])

            #获取前端用户的角色和资源
            get_jue_res = rbac.get_page_jue_resource(res['id'])
            resall.extend(get_jue_res)    

            #获取后端权限
            reshouall = acl.get_interface_resource(res['id'])
            #把后端所有权限存入redis
            key = 'interface'+str(res['id'])
            r.set_add(key,reshouall)

            return jsonify({"code":200,'mes':'登录成功','userid':res['id'],'name':res['name'],'mobile':res['mobile'],'token':token,'pagelist':resall})
        else:
            return jsonify({"code":20030,'mes':'用户名或密码有误'})
    else:
        return jsonify({"code":20020,'mes':'该用户不从在'})


#构建简单的2层分类
def gettwocate(data):
    lst = []
    idlist = []
    #把顶级id方在lst里
    for i in data:
        id = i['pid']
        #去掉重复的父id  列入 有4个 5 5 9 15  只剩下5 9 15 就是顶级父类
        if id not in idlist:
            lst.append({'id':id,'name':i['pname'],'son':[]})
            idlist.append(id)
    #循环添加数据的列表 需要下表
    for i,value in enumerate(lst):
        for j in data:
            # print(j)
            if value['id'] == j['pid']:
                lst[i]['son'].append({'id':j['id'],'name':j['name'],'url':j['url']})

    return  lst



#用户资源
@bp_user.route('/usermanage/')
async def usermanage():
    # uid  = request.args.get('uid')
    uid = 4
    # print(uid)
    #根据用户id查看用户有哪些权限
    # sql = "select r.id,r.name,re.name as pname,re.id as pid,r.url from resource as r left join user_resource as ur on r.id=ur.resourceid left join resource as re on  r.pid=re.id left join    where r.type=1 and ur.userid=%d"%(int(uid))
    # res = db.find_all(sql)
    sql = "select r.name,r.url,r.id,pr.id as pid,pr.name as pname from user_resource as ur left join resource as r on ur.resourceid=r.id left join resource as pr on pr.id=r.pid where ur.userid=%d and r.type=1 union select r.name,r.url,r.id,pr.id as pid,pr.name as pname from user_jue as ur left join jue_resource as rr on ur.jueid=rr.jueid left join resource as r on rr.resourceid=r.id left join resource as pr on pr.id=r.pid where ur.userid=%d and r.type=1"%(int(uid),int(uid))
    res = db.find_all(sql)

    lst = gettwocate(res)
    return jsonify({'code':200,'list':lst})


#穿梭表  获取管理员权限
@bp_user.route('/getadmin/')
async def getadmin():
    uid = 4
    #先查看管理员对用那个角色  角色对应那些资源 r.id,
    sql = "select r.id,r.name as rname from users as u left join user_jue as uj on u.id=uj.userid left join jue_resource as jr on uj.jueid=jr.jueid left join resource as r on jr.resourceid = r.id where u.id=%d"%(int(uid))

    res = db.find_all(sql)
    return jsonify({'code':200,'list':res})

#获取用户权限
@bp_user.route('/getuser/',methods=['POST','GET'])
async def getuser():
    if request.method == 'GET':
        sql = "select * from users"
        res = db.find_all(sql)
        return jsonify({'code':200,'list':res})
    else:
        userid = request.form.get('userid')
        values = eval(request.form.get('values'))
        print(values)
        #写入用户资源表   角色资源表是固定的
        for i in values: 
            print(i)
            sql = "insert into user_resource value(%d,%d)"%(int(userid),int(i))
            db.insert(sql)
        return jsonify({'code':200})




#获取角色资源  角色管理
@bp_user.route('/getjue/',methods=['POST','GET'])
async def getjue():
    if request.method == 'GET':
        #获取所有角色  [{'name':总经理,'resource':"[1,2,3,4]"}
        #               {'name':经理,'resource':"[1,2,3]"}]
        sql = "select *  from jue inner join jue_resource as jr on jue.id=jr.jueid"
        res = db.find_all(sql)
        # print(res)
        lst = []
        lst1=[]
        for i in res:
            if i['id'] not in lst1:
                lst1.append(i['id'])
                lst.append({'id':i['id'],'name':i['name'],'resource':[]})
        for j,k in enumerate(lst):
            for i in res:
                if k['id'] ==i['id']:
                    lst[j]['resource'].append(i['resourceid'])


        return jsonify({'code':200,'list':lst})
    #角色继承
    elif request.method =='POST':
        uid= request.form.get('uid')
        jueid = request.form.get('jueid')
        value = eval(request.form.get('value'))
        # print(value,type(value))
        # #根据角色id 查用户id
        # sql = "select * from user_jue where jueid=%d"%(int(jueid))
        # res = db.find_one(sql)
        # # print(res)
        # 查看用户权限表 有数据删除
        sql1 = 'delete from user_resource where userid=%d'%(int(uid))
        db.delete(sql1)
        for i in value:
            print(i,type(i))
            sql2  = "insert  into  user_resource value(%d,%d)"%(int(uid),int(i))
            print('pasd')
            db.insert(sql2)
        
        return jsonify({"code":200})

@bp_user.route('/juemutex/')
async def juemutex():
    #角色互斥
        uid = request.args.get('userid')
        if uid:
            #获取那个角色为另一个角色添加该角色权限
            jue1 = request.args.get('jue1')
            value1 = eval(request.form.get('value1'))
            jue2 = request.args.get('jue2')
            value2 = eval(request.form.get('value2'))
            #查看该角色和那个角色冲突
            sql1 = "select * from juemutex where jue1=%d"%(int(jue1))
            res1 = db.find_all(sql1)
            for i in res1:
                if int(i['jue1']) == int(jue2):
                    return '不能为该角色添加此角色权限'
            #去重给该角色添加权限
            for j in value1:
                if j not in value2:
                    value2.append(j)
            for k in value2:
                sql3 = "insert into user_resource values(%d,%d)"%(int(uid),int(k))
                db.insert(sql3)

        return jsonify({"code":200})


#装饰器

def getPormition(func):
    #蓝图都用@  装饰器也用@ 冲突  这个函数解决冲突
    @functools.wraps(func)
    def wrapper(*args,**kwargs):
        #获取token  目的需要id
        token = request.headers['Authorization']
        #解析token 拿id
        payload = myjwt.jwt_decode(token)
        uid = payload['data']['userid']
        #根据ID查询职务
        sql = "select jobcode from  job where id=%d"%(int(uid0))
        level = db.find_one(sql)
        if level['jobcode'] == '003':
            #获取当前ip
            ip = request.remote_addr
            #获取当前时间
            time = datetime.datetime.strftime(datetime.datetime.now(), "%Y-%m-%d")
            values = r.hget_gets('rbac')
            for k,v in values.items():
                key = str(k,encoding='utf8')
                if key == 'ip':
                    if ip !=str(v,encoding='utf8'):
                        return 'ip限制'
                if key == 'time':
                    timev = eval(v)
                    if time<timev[0] or time>timev[1]:
                        return '时间限制'
            if request.method not in ['GET','PUT']:
                return '只能访问get'
        return func(*args,**kwargs)
    return wrapper


#abac 属性判断
@bp_user.route('/abacif/')
async def abacif():
    opt = request.method
    print(opt)
    #显示方法是读取才可以执行
    if opt == 'GET':
        key = 'abac'
        r.hset_set(key, 'ip', '127.0.0.1')
        r.hset_set(key, 'level', '003')
        r.hset_set(key, 'time', "['2021-10-1','2021-11-01']")
        values = r.hget_gets(key)
        # print(values)
        for (k,v) in values.items():
            # print(k)
            #判断属性是否是时间 
            if str(k,encoding='utf8') == 'time':
                print(eval(v))

    return 'ok'


#工作流
#获取工作流
@bp_user.route('/getwork/')
async def getwork():
    #获取前端数据 后端写入
    sql = "select * from  workflow"
    res = db.find_all(sql)
    return jsonify({'code':200,'list':res})

#获取工作流的数据源  修改工作流  给工作流添加信息
@bp_user.route('/getorigin/',methods=['POST',"GET",'PUT'])
async def getorigin():
    if request.method == 'POST':
        #文件应该保存在static里 这边没写
        data= get_data()
        userid = int(data['userid'])
        #领导审核列表
        nextlead = eval(data['nextlead'])
        # print(nextlead,type(nextlead))
        # #当前需要审核的领导
        # nowlead = nextlead[0]
        #获取值 params
        params  = data['data']
        #获取标题
        title = eval(params)['姓名']+' '+data['name']

        #判断是否点错 后穿过来的id 例如传过来[1,2,2,2,3,3,4,6] 其中2 和3点错了  2最后还是要添加  3是完全点错不添加 结果[1,2,4,6]
        newlead =[]
        for i in nextlead:
            if nextlead.count(i) %2 != 0:
                if i not in newlead:
                    newlead.append(i)

        #获取当前查的第一个领导名
        onelead = newlead[0]
        # print(newlead)
        # print(onelead)
        #吧记录写在数据库
        sql = "insert into task value(0,%d,'%s',1,'%s','%s','%s')"%(userid,title,json.dumps(newlead),params,onelead)
        db.insert(sql)
        #工作流 串行存入redis
        key = 'holiday'+str(onelead)

        r.hset_set(key,title,params)

        return jsonify({'code':200})

    elif request.method =='GET':
        #数据库只读取一次 太灵活 读到储存在redis里 所以先获取redis
        value  = r.str_get('getrrigin')
        if value:
            #去出来返回
            lst = json.dumps(eval(r.set_get('dataresource')))
            return jsonify({'code':200,'list':lst})
            pass
        else:
            #没有 查找 储存 
            sql = "select * from data_source"
            res = db.find_all(sql)
            # print(res)
            lst = []
            if res:
                #有数据 查看请假表的所有数据 重构
                for i in res:
                    dic={"id":i['id'],"name":i["name"]}
                    sql1 = "select id,name from %s "%(i['tablename'])
                    res1 =  db.find_all(sql1)
                
                    dic['mes'] = res1
                    lst.append(dic)
            r.str_set('dataresource', json.dumps(lst))
            # print(lst)
        return jsonify({'code':200,'list':lst})


    else:
        data = get_data()
        sql = 'select * from workflow where id=%d'%(int(data['id']))
        res = db.find_one(sql)
        # print(res)
        if res:
            sql1 = "update workflow set params='%s' where id=%d" %(data['params'],int(data['id'])) 
            # print(sql1)
            db.update(sql1)
            return jsonify({'code':200})



#申请工作台的页面
@bp_user.route('/appwork/')
async def appwork():
    
    #获取参数
    sql = "select * from workflow"
    res = db.find_all(sql)
    # print(res)
    return jsonify({'code':200,'list':res})

#获取下一个批准人 与257行代码 关联
def getdeptdata(data):
    tree = {}
    list=[]
    for i in data:
        tree[i['id']] = i
    
    for j in data:
        pid = j['pid']
        if not pid:
            list.append(j)
        else:
            #没在父类0里给0加children 没在1里给1加
            if 'children' not in tree[pid]:
                tree[pid]['children']=[]
            #查询此部门下所有员工  id as sid  id是用户的回合职务id重复 这边起别名
            sql = "select id as sid,name,dept_id from users where dept_id=%d"%(j['id'])
            res = db.find_all(sql)
            userlist=[]
            if res:
                userlist=res
            #吧用户添加到部门类下
            j['children'] = userlist
            tree[pid]['children'].append(j)

    return list

@bp_user.route('/getlead/')
def getlead():
    #获取所有公司及所有部门
    sql = "select * from dept"
    res = db.find_all(sql)
    mes = getdeptdata(res)
    return jsonify({'code':200,'list':mes})

#工作流 任务表提交 执行 
@bp_user.route('/workdeal/',methods=['POST',"GET"])
def workdeal():
    #获取处理任务
    if request.method == 'GET':
        userid = request.args.get('userid')
        #查看是否是该用户 用该用token 这边用id暂时用下
        sql = "select * from users where id=%d"%(int(userid))
        res = db.find_one(sql)
        if res:
            key = 'holiday'+str(res['id'])
            
            holiday = r.hget_gets(key)
            # print(holiday)
            lst=[]
            for i,g in holiday.items():
                dic = {'titles':str(i,encoding='utf8'),'params':str(g,encoding='utf8')}
                lst.append(dic)
            # print(lst)
            # mes = 1
            # mes = str(holiday, encoding='utf8')
            # # holiday = str(r.hget_gets(key),encoding='utf8')
            # print(holiday)
            return jsonify({'code':200,'list':lst})
    #提交  是否提交 1是未审核 2是待审核 3是完成审核
    else:
        data = get_data()
        radio =int(data['radio'])
        content = data['content']
        title = data['title']
        userid = data['userid']
        # print(radio,type(radio))
        #查询 该名称的数据修改状态
        name = title.split(' ')[0]
        stime = datetime.datetime.strftime(datetime.datetime.now(), "%Y-%m-%d %H:%M:%S")
        sql = "select * from  task where title='%s'"%(title)
        res = db.find_one(sql)
        
        # return 'of'
        if not res:
            #没有申请
            return jsonify({'code':10020,'mes':'暂无申请'})

        #判断同意  且 是最后一个领导审核
        if radio == 2 and int(res['leadid']) == int(eval(res['leadnext'])[-1]):
            #审核状态变为3  删除redis的数据
            sql3 = 'update task set status=3 where title="%s"'%(title)
            db.update(sql3)
            #删除redis
            key = 'holiday'+str(userid)
            r.hdel_del(key,title)
            sql5 = "insert into audit_record values(0,%d,%d,'%s',1,'%s','%s')"%(int(res['id']),int(res['userid']),name,content,stime)
            db.insert(sql5)
            return jsonify({'code':200,'mes':'最终审核通过'})
        #2 代表同意 乳沟还有后续领带 状态不变
        elif radio == 2:
            
            #这边 可能审核人不一样 后期会出错 要用try捕获异常  暂时没写
            index = eval(res['leadnext']).index(int(userid))
            sql1 = 'update task set status=%d,leadid=%d where title="%s"'%(int(radio),eval(res['leadnext'])[index+1],title)
            # print(sql1)
            db.update(sql1)
            print('asdasd')
            # 把上一级从radis删掉 
            # 哈希的key
            key = 'holiday'+str(userid)
            r.hdel_del(key,title)
            # #加入下一级
            keys = 'holiday'+str(eval(res['leadnext'])[index+1])
            r.hset_set(keys,title,res['params'])
            #添加到记录表中
            sql5 = "insert into audit_record values(0,%d,%d,'%s',1,'%s','%s')"%(int(res['id']),int(res['userid']),name,content,stime)
            db.insert(sql5)
            return jsonify({'code':200})

        elif  radio == 1 and  int(res['leadid']) == int(eval(res['leadnext'])[0]):
            #第一个领导没同意同时删除数据 删除redis
            sql4 =  "delete from task where title='%s'"%(title)
            db.delete(sql4)
            key = 'holiday'+str(userid)
            r.hdel_del(key,title)
            sql5 = "insert into audit_record values(0,%d,%d,'%s',2,'%s','%s')"%(int(res['id']),int(res['userid']),name,content,stime)
            db.insert(sql5)

            return jsonify({'code':20030,'mes':'申请有误，请重新申请'})
        elif  radio == 1:
            #回退
            index = eval(res['leadnext']).index(int(res['leadid']))
            sql2 = 'update task set status=2,leadid=%d  where title="%s"'%(eval(res['leadnext'])[index-1],title)
            db.update(sql2)
            key = 'holiday'+str(userid)
            r.hdel_del(key,title)
            # #加入下一级
            keys = 'holiday'+str(eval(res['leadnext'])[index-1])
            r.hset_set(keys,title,res['params'])
            sql5 = "insert into audit_record values(0,%d,%d,'%s',2,'%s','%s')"%(int(res['id']),int(res['userid']),name,content,stime)
            db.insert(sql5)
            return jsonify({'code':20020,'mes':'请返回上一级'})

#我的申请详情
@bp_user.route('/myapply/',methods=['POST','GET'])
async def myapply():
    if request.method =='POST':
        pass
    else:
        userid = request.args.get('userid')
        #查询我的申请记录
        sql = "select ar.id,t.params,ar.username,t.status,ar.add_time,ar.reason,ar.id_agree,t.leadid from audit_record as ar left join task as t on ar.userid=t.userid where ar.userid=%d "%(int(userid))
        res = db.find_all(sql)
        dic={}
        for i in res:
            params = eval(i['params'])
            dic['params'] = params
        return jsonify({'code':20020,'list':res,'params':dic})
        
                

        




